import numpy as np
import cv2
import os


class Parameter:
    rootDir = os.getcwd()
    assetRootDir = rootDir + "/asset"
    resultRootDir = rootDir + "/result"


board1_1_points = np.float32([[180, 697], [188, 1011], [469, 943], [467, 710]])
board1_2_points = np.float32([[581, 806], [584, 990], [716, 992], [713, 806]])
board1_3_points = np.float32([[468, 19], [483, 714], [592, 719], [582, 121]])

board2_1_points = np.float32([[1816, 376], [1808, 732], [2098, 728], [2112, 254]])
board2_2_points = np.float32([[1286, 625], [1285, 871], [1563, 954], [1566, 542]])


def transform2board(src_img: np.ndarray, dst_img: np.ndarray, src_points, dst_points):
    # 计算透视变换矩阵
    matrix = cv2.getPerspectiveTransform(src_points, dst_points)

    # 应用透视变换
    transformed_src = cv2.warpPerspective(
        src_img, matrix, (dst_img.shape[1], dst_img.shape[0])
    )

    # 创建一个掩码，用于将变换后的图片融合到背景中
    mask = np.zeros_like(dst_img)
    cv2.fillPoly(mask, [np.int32(dst_points)], (255, 255, 255))

    # 将变换后的图片与背景融合
    masked_transformed = cv2.bitwise_and(transformed_src, mask)
    masked_board = cv2.bitwise_and(dst_img, cv2.bitwise_not(mask))
    return cv2.add(masked_board, masked_transformed)


if __name__ == "__main__":
    board_path = Parameter.assetRootDir + "/board.jpg"
    panda_path = Parameter.assetRootDir + "/panda.jpeg"
    red_panda_path = Parameter.assetRootDir + "/red_panda.jpg"
    result_path = Parameter.resultRootDir + "/task4/result.jpg"

    board_img = cv2.imread(board_path)
    panda_img = cv2.imread(panda_path)
    red_panda_img = cv2.imread(red_panda_path)

    # 顶点顺序统一为：左上角开始，逆时针顺序
    panda_points = np.float32(
        [
            [0, 0],
            [0, panda_img.shape[0]],
            [panda_img.shape[1], panda_img.shape[0]],
            [panda_img.shape[1], 0],
        ]
    )

    red_panda_points = np.float32(
        [
            [0, 0],
            [0, red_panda_img.shape[0]],
            [red_panda_img.shape[1], red_panda_img.shape[0]],
            [red_panda_img.shape[1], 0],
        ]
    )

    board_img = transform2board(panda_img, board_img, panda_points, board1_1_points)
    board_img = transform2board(panda_img, board_img, panda_points, board1_2_points)
    board_img = transform2board(panda_img, board_img, panda_points, board1_3_points)

    board_img = transform2board(
        red_panda_img, board_img, red_panda_points, board2_1_points
    )
    board_img = transform2board(
        red_panda_img, board_img, red_panda_points, board2_2_points
    )

    cv2.imwrite(result_path, board_img)
